﻿Option Strict On
Option Explicit On
Option Infer On

Imports System
Imports GenDotNet.TemplateSupport.StandardAttributeExtensions
Imports GenDotNet.Task.Common
Imports GenDotNet.Model.Common
Imports System.Xml.Linq

Public MustInherit Class TemplateBase
   Implements ITemplate

   'Private mCurrent As IBaseData
   Private stopwatch As New Diagnostics.Stopwatch
   Private mRootData As IRootData
   Private mNamingFactory As NamingFactory
   Public MustOverride ReadOnly Property Id() As Guid

   Protected MustOverride Function GenerateFile(ByVal current As IBaseData) As String
   Protected MustOverride Function GetFileName(ByVal current As IBaseData) As String

   Protected Sub New()
   End Sub


#Region "ITemplate interface"
   Protected Function Generate( _
            ByVal dataName As String, _
            ByVal rootData As IRootData, _
            ByRef fileName As String) _
            As String _
            Implements ITemplate.Generate
      Me.mRootData = rootData
      Dim current = rootData.GetItem(dataName)
      If ShouldOutput(current) Then
         fileName = GetFileName(current)
         Return Me.GenerateFile(current)
      End If
      Return Nothing

      'Me.mBaseElement = element
      ' TODO: THis must be moved across teh metadata boundary as this class should have no dependency on file structure
      'Dim name = element.@Name
      'Console.WriteLine(stopwatch.Elapsed.Milliseconds)
      'Console.Write(name & Microsoft.VisualBasic.ControlChars.Tab)
      'stopwatch.Start()
      'SetUp(mBaseElement)
      'Console.Write(stopwatch.Elapsed.Milliseconds & Microsoft.VisualBasic.ControlChars.Tab)
      'stopwatch.Reset()
      'stopwatch.Start()
      'Dim x = GenerateFile()
      'Console.Write(stopwatch.Elapsed.Milliseconds & Microsoft.VisualBasic.ControlChars.Tab)
      'stopwatch.Reset()
      'stopwatch.Start()
      'Return x
   End Function

   ''' <summary>
   ''' Allows templates to self filter and refuse to output in specific data 
   ''' conditions. If the refusal is because of a data error, an exception should
   ''' be raised or the error logged, details of which are not worked out.
   ''' </summary>
   ''' <param name="current"> 
   ''' The current data item as an IBaseData. Overriding methods are expected to
   ''' cast this to the known type
   ''' </param>
   ''' <returns>True if the output shoudl be created, otherwise false</returns>
   Protected Overridable Function ShouldOutput(ByVal current As IBaseData) As Boolean
      Return True
   End Function

#End Region

   '' This exists only for testing, because private accessors are misbehaving today.
   'Protected Sub SetBaseElement(ByVal element As XElement)
   '   Me.mBaseElement = element
   'End Sub

#Region "Properties"
   'Protected ReadOnly Property BaseElement() As XElement
   '   Get
   '      Return mBaseElement
   '   End Get
   'End Property

   Protected Property NamingFactory() As NamingFactory
      Get
         If mNamingFactory Is Nothing Then
            mNamingFactory = New NamingFactory
         End If
         Return mNamingFactory
      End Get
      Set(ByVal value As NamingFactory)
         mNamingFactory = value
      End Set
   End Property

   Protected ReadOnly Property TemplateName() As String
      Get
         Return Me.GetType.Name & "(" & Me.GetType.Assembly.FullName & ")"
      End Get
   End Property

   Public ReadOnly Property RootData() As IRootData
      Get
         Return mRootData
      End Get
   End Property

#End Region



#Region "Extension methods"
   'Public Overridable Function CommaEndingNoWrap(ByVal last As Object, ByVal par As Object) As String
   '   Return CommaEnding(last, par, False)
   'End Function

   'Public Overridable Function CommaEnding(ByVal last As Object, ByVal par As Object) As String
   '   Return CommaEnding(last, par, True)
   'End Function

   'Public Overridable Function CommaEnding( _
   '      ByVal last As Object, _
   '      ByVal par As Object, _
   '      ByVal wrap As Boolean) _
   '      As String
   '   Return LiteralEnding(commaString, last, par, wrap)
   'End Function

   'Public Overridable Function LiteralEndingNoWrap( _
   '          ByVal literal As String, _
   '          ByVal last As Object, _
   '          ByVal par As Object) _
   '          As String
   '   Return LiteralEnding(literal, last, par, False)
   'End Function

   'Public Overridable Function LiteralEnding( _
   '         ByVal literal As String, _
   '         ByVal last As Object, _
   '         ByVal par As Object) _
   '         As String
   '   Return LiteralEnding(literal, last, par, True)
   'End Function

   'Public Overridable Function LiteralEnding( _
   '         ByVal literal As String, _
   '         ByVal last As Object, _
   '         ByVal par As Object, _
   '         ByVal wrap As Boolean) _
   '         As String
   '   If String.IsNullOrEmpty(literal) Then
   '      Return String.Empty
   '   End If
   '   If last IsNot Nothing AndAlso last IsNot par Then
   '      Return literal & If(wrap, wrapString, String.Empty)
   '   Else
   '      Return String.Empty
   '   End If
   'End Function

#End Region

End Class

